/**
 * 插件管理器 - 管理所有插件的生命周期
 * 提供插件的安装、卸载、启用、禁用功能
 */

import type { Plugin, ScheduleContext } from '../types'

export class PluginManager {
  private plugins: Map<string, Plugin>
  private context: ScheduleContext | null

  constructor() {
    this.plugins = new Map()
    this.context = null
  }

  /**
   * 设置上下文
   * @param context 调度上下文
   */
  setContext(context: ScheduleContext): void {
    this.context = context
  }

  /**
   * 安装插件
   * @param plugin 插件实例
   */
  async install(plugin: Plugin): Promise<void> {
    if (this.plugins.has(plugin.id)) {
      throw new Error(`Plugin "${plugin.id}" is already installed`)
    }

    // 检查依赖
    if (plugin.dependencies) {
      for (const depId of plugin.dependencies) {
        if (!this.plugins.has(depId)) {
          throw new Error(`Plugin "${plugin.id}" requires "${depId}" but it is not installed`)
        }
      }
    }

    // 设置默认启用状态
    plugin.enabled = plugin.enabled !== false

    // 注册插件
    this.plugins.set(plugin.id, plugin)

    // 调用安装钩子
    if (plugin.onInstall && this.context) {
      await plugin.onInstall(this.context)
    }

    // 如果插件启用，调用启用钩子
    if (plugin.enabled && plugin.onEnable && this.context) {
      await plugin.onEnable(this.context)
    }

    console.log(`[PluginManager] Plugin "${plugin.name}" (${plugin.id}) installed`)
  }

  /**
   * 卸载插件
   * @param pluginId 插件ID
   */
  async uninstall(pluginId: string): Promise<void> {
    const plugin = this.plugins.get(pluginId)
    if (!plugin) {
      throw new Error(`Plugin "${pluginId}" is not installed`)
    }

    // 检查是否有其他插件依赖此插件
    for (const [id, p] of this.plugins) {
      if (p.dependencies?.includes(pluginId)) {
        throw new Error(`Cannot uninstall plugin "${pluginId}" because "${id}" depends on it`)
      }
    }

    // 如果插件启用，先禁用
    if (plugin.enabled) {
      await this.disable(pluginId)
    }

    // 调用卸载钩子
    if (plugin.onUninstall && this.context) {
      await plugin.onUninstall(this.context)
    }

    // 移除插件
    this.plugins.delete(pluginId)

    console.log(`[PluginManager] Plugin "${plugin.name}" (${pluginId}) uninstalled`)
  }

  /**
   * 启用插件
   * @param pluginId 插件ID
   */
  async enable(pluginId: string): Promise<void> {
    const plugin = this.plugins.get(pluginId)
    if (!plugin) {
      throw new Error(`Plugin "${pluginId}" is not installed`)
    }

    if (plugin.enabled) {
      return
    }

    plugin.enabled = true

    if (plugin.onEnable && this.context) {
      await plugin.onEnable(this.context)
    }

    console.log(`[PluginManager] Plugin "${plugin.name}" (${pluginId}) enabled`)
  }

  /**
   * 禁用插件
   * @param pluginId 插件ID
   */
  async disable(pluginId: string): Promise<void> {
    const plugin = this.plugins.get(pluginId)
    if (!plugin) {
      throw new Error(`Plugin "${pluginId}" is not installed`)
    }

    if (!plugin.enabled) {
      return
    }

    plugin.enabled = false

    if (plugin.onDisable && this.context) {
      await plugin.onDisable(this.context)
    }

    console.log(`[PluginManager] Plugin "${plugin.name}" (${pluginId}) disabled`)
  }

  /**
   * 获取插件
   * @param pluginId 插件ID
   */
  getPlugin(pluginId: string): Plugin | undefined {
    return this.plugins.get(pluginId)
  }

  /**
   * 获取所有插件
   */
  getAllPlugins(): Plugin[] {
    return Array.from(this.plugins.values())
  }

  /**
   * 获取所有已启用的插件
   */
  getEnabledPlugins(): Plugin[] {
    return this.getAllPlugins().filter(p => p.enabled)
  }

  /**
   * 检查插件是否已安装
   * @param pluginId 插件ID
   */
  has(pluginId: string): boolean {
    return this.plugins.has(pluginId)
  }

  /**
   * 检查插件是否已启用
   * @param pluginId 插件ID
   */
  isEnabled(pluginId: string): boolean {
    return this.plugins.get(pluginId)?.enabled || false
  }

  /**
   * 调用插件方法
   * @param pluginId 插件ID
   * @param methodName 方法名
   * @param args 方法参数
   */
  callPluginMethod(pluginId: string, methodName: string, ...args: unknown[]): unknown {
    const plugin = this.plugins.get(pluginId)
    if (!plugin) {
      throw new Error(`Plugin "${pluginId}" is not installed`)
    }

    if (!plugin.enabled) {
      throw new Error(`Plugin "${pluginId}" is not enabled`)
    }

    const method = plugin.methods?.[methodName]
    if (!method) {
      throw new Error(`Plugin "${pluginId}" does not have method "${methodName}"`)
    }

    return method(...args)
  }

  /**
   * 触发所有插件的数据变更钩子
   * @param data 变更的数据
   */
  async notifyDataChange(data: unknown): Promise<void> {
    const promises: Promise<void>[] = []

    for (const plugin of this.getEnabledPlugins()) {
      if (plugin.onDataChange && this.context) {
        const result = plugin.onDataChange(this.context, data)
        if (result instanceof Promise) {
          promises.push(result)
        }
      }
    }

    await Promise.all(promises)
  }

  /**
   * 清除所有插件
   */
  clear(): void {
    this.plugins.clear()
  }
}
